package com.even.camerarecoder.aac

import java.nio.ByteBuffer

/** ADTS头信息添加工具，ADTS头含义参考：https://wiki.multimedia.cx/index.php/ADTS */
object ADTSUtil {
    /** 只保存了ADTS头中不变化的那部分信息  */
    private var adtsPart = 0xFFF94000001FFCL
    /** 保存了ADTS头中的完整信息  */
    private var adtsFull = 0L
    private var byte_0: Byte = 0
    private var byte_1: Byte = 0
    private var byte_2: Byte = 0
    private var byte_6: Byte = 0

    /** 采样频率对应的索引，具体参考：https://wiki.multimedia.cx/index.php/MPEG-4_Audio#Sampling_Frequencies */
    private val sampleRateIndexMap = mapOf(
        96000 to 0, 88200 to 1, 64000 to 2, 48000 to 3,
        44100 to 4, 32000 to 5, 24000 to 6, 22050 to 7,
        16000 to 8, 12000 to 9, 11025 to 10, 8000 to 11,
        7350 to 12)

    /**
     * 初始化ADTS头
     * @param sampleRateInHz 音频的采样频率，
     * @param channelCount 音频的声道数量
     */
    fun initADTS(sampleRateInHz: Int, channelCount: Int) {
        val sampleRateIndex = sampleRateIndexMap[sampleRateInHz] ?: error("ADTS不支持${sampleRateInHz}采样率，具体支持参考sampleRateIndexMap集合")
        adtsPart = adtsPart or (sampleRateIndex.toLong() shl 34) or (channelCount.toLong() shl 30)
        byte_0 = (adtsPart ushr 48).toByte() // 右移48 = （7字节 - 1） * 8
        byte_1 = (adtsPart ushr 40).toByte() // 右移40 = （6字节 - 1） * 8
        byte_2 = (adtsPart ushr 32).toByte() // 右移32 = （5字节 - 1） * 8
        byte_6 = adtsPart.toByte()           // 右移 0 = （1字节 - 1） * 8
    }

    /** 往oneADTSFrameBytes数组中的最前面7个字节中填入ADTS头信息  */
    fun addADTS(oneADTSFrameBytes: ByteArray) {
        adtsFull = adtsPart or (oneADTSFrameBytes.size.toLong() shl 13)
        oneADTSFrameBytes[0] = byte_0
        oneADTSFrameBytes[1] = byte_1
        oneADTSFrameBytes[2] = byte_2
        oneADTSFrameBytes[3] = (adtsFull ushr 24).toByte() // 右移24 = （4字节 - 1） * 8
        oneADTSFrameBytes[4] = (adtsFull ushr 16).toByte() // 右移16 = （3字节 - 1） * 8
        oneADTSFrameBytes[5] = (adtsFull ushr 8).toByte()  // 右移 8 = （2字节 - 1） * 8
        oneADTSFrameBytes[6] = byte_6
    }

    /** 往oneADTSFrameBytes数组中的最前面7个字节中填入ADTS头信息  */
    fun addADTS(oneADTSFrameBytes: ByteBuffer, length: Long) {
        adtsFull = adtsPart or (length shl 13)
        oneADTSFrameBytes.put(byte_0)
        oneADTSFrameBytes.put(byte_1)
        oneADTSFrameBytes.put(byte_2)
        oneADTSFrameBytes.put((adtsFull ushr 24).toByte()) // 右移24 = （4字节 - 1） * 8
        oneADTSFrameBytes.put((adtsFull ushr 16).toByte()) // 右移16 = （3字节 - 1） * 8
        oneADTSFrameBytes.put((adtsFull ushr 8).toByte())  // 右移 8 = （2字节 - 1） * 8
        oneADTSFrameBytes.put(byte_6)
        /*adtsFull = adtsPart or (length shl 13)
        oneADTSFrameBytes.put(0, byte_0)
        oneADTSFrameBytes.put(1, byte_1)
        oneADTSFrameBytes.put(2, byte_2)
        oneADTSFrameBytes.put(3, (adtsFull ushr 24).toByte()) // 右移24 = （4字节 - 1） * 8
        oneADTSFrameBytes.put(4, (adtsFull ushr 16).toByte()) // 右移16 = （3字节 - 1） * 8
        oneADTSFrameBytes.put(5, (adtsFull ushr 8).toByte())  // 右移 8 = （2字节 - 1） * 8
        oneADTSFrameBytes.put(6, byte_6)
        oneADTSFrameBytes.position(7)*/
    }
}